"""
抽象的UI层。
"""
import abc
import typing
from loguru import logger

from elio.core.base import BaseSessionParentType

LayerType = typing.TypeVar("LayerType", bound='Layer')


class Layer(typing.Generic[BaseSessionParentType], metaclass=abc.ABCMeta):
    """
    基础UI层。
    """
    def __init__(self, parent: BaseSessionParentType):
        self._parent = parent

    @classmethod
    async def create(
            cls: typing.Type[LayerType], parent: BaseSessionParentType, *args: typing.Any, **kwargs: typing.Dict
    ) -> LayerType:
        """
        创建一个UI层的实例。
        """
        layer = cls(parent)
        await layer.on_create(*args, **kwargs)
        return layer

    async def destroy(self):
        """
        销毁本对象。
        """
        await self.on_destroy()

    async def on_back_pressed(self) -> bool:
        """
        当用户按下设备的返回键后触发。
        返回True表示不拦截事件，返回False表示拦截事件。
        """
        if self.parent.is_debug:
            logger.debug('%s: onBackPressed.' % self.__class__.__name__)
        return True

    @abc.abstractmethod
    async def on_create(self, *args: typing.Any, **kwargs: typing.Dict):
        """
        当UI层对象创建完毕则自动调用此方法。
        """
        if self.parent.is_debug:
            logger.debug('%s: onCreate.' % self.__class__.__name__)

    @abc.abstractmethod
    async def on_destroy(self, *args: typing.Any, **kwargs: typing.Dict):
        """
        当UI层对象将要销毁则自动调用此方法。
        """
        if self.parent.is_debug:
            logger.debug('%s: onDestroy.' % self.__class__.__name__)

    @abc.abstractmethod
    async def on_show(self):
        """
        被压入layer栈顶（或在他之上的layer移出后）时自动调用此方法，通常在此方法中创建小部件，可重写此方法来实现自己关于UI的业务代码。
        """
        if self.parent.is_debug:
            logger.debug('%s: onShow.' % self.__class__.__name__)

    @abc.abstractmethod
    async def on_hide(self):
        """
        从layer栈顶移出（或被其他layer覆盖）时自动调用此方法，通常在此方法中销毁小部件，可重写此方法来实现自己关于UI的业务代码。
        """
        if self.parent.is_debug:
            logger.debug('%s: onHide.' % self.__class__.__name__)

    @abc.abstractmethod
    async def on_resume(self):
        """
        如果当前layer处于栈顶，activity从后台恢复时自动调用此方法，可重写此方法来实现自己的业务代码。
        """
        if self.parent.is_debug:
            logger.debug('%s: onResume.' % self.__class__.__name__)

    @abc.abstractmethod
    async def on_pause(self):
        """
        如果当前layer处于栈顶，当activity进入暂停模式时自动调用此方法，可重写此方法来实现自己的业务代码。
        """
        if self.parent.is_debug:
            logger.debug('%s: onPause.' % self.__class__.__name__)

    @property
    def parent(self) -> BaseSessionParentType:
        """
        获取当前UI层基于的父对象。
        """
        return self._parent
